Туториал по Порталам
Версия 2.0 от 18.09.2021
В данной статье я расскажу, как в RPGMaker MV / MZ сделать систему порталов, максимально похожую на порталы из серии игр "Portal".
Демка на MV, но в MZ делается 100% также (изначально было реализовано в MZ).
Будет "много букв" и немного картинок.
Видео-демонстрация в первом сообщении после данного туториала.
TL;DR
Сделать можно, но с рядом оговорок. Качайте демку, открывайте мейкером и смотрите.
ВСТУПЛЕНИЕ
Предисловие.
Я давно хотел сделать головоломку в мейкере, и пытался вспомнить игры с хорошими головоломками для отправной точки.
В памяти, как ни банально, всплывала только серия «Portal». Сначала я говорил себе, что на мейкере это нереализуемо в принципе (сразу скажу – реализуемо, но не 100% и с большим количеством оговорок), но…потом я задал себе вопрос.
Почему?
Нужно разобраться.
Разбираемся!
Идея.
Давайте разложим механику Порталов в «Portal» на части.
Что мы имеем:
1. ЛКМ – в указанной курсором мышки точке образуется сущность «Портал Синий».
2. ПКМ – в указанной курсором мышки точке образуется сущность «Портал Желтый».
3. Порталы открываются не на всех поверхностях.
4. После открытия обоих Порталов все остальные игровые объекты, при совпадении координат с одним из Порталов, перемещаются к другому.
5. При этом, скорость и направление движения игровых объектов не меняются.
6. В порталы можно смотреть.
7. Между порталами можно «зависнуть».
Как-то так. Но можно и кое-что объединить для удобства восприятия, а именно:
1. Работа с мышкой.
2. Перенос объектом между Порталами.
3. Дополнительные качества Порталов.
Теперь нам удобно есть слона. Пройдемся по пунктам, что можно реализовать в мейкере?
МЫШКА
Общие размышления о мышке.
В мейкерах MV и MZ управление мышкой есть «из-коробки». Но оно только запускает поиск пути (ЛКМ) и открывает меню (ПКМ). Хмм…хорошо что есть и что различается ЛКМ и ПКМ. Все остальное плохо.
А что нам нужно?
Нужно:
1. Отключение стандартного поведения (поиска пути и вызова меню).
2. Раздельное получение координат клетки карты от кликов ЛКМ и ПКМ.
3. Раздельный вызов событий на клики ЛКМ и ПКМ.
Из-коробки в редакторе мейкера это недоступно. Но доступно ли в движке в принципе? Легкий сеанс гуглотерапии говорит, что в движке это все есть!
Отключение стандартного поведения.
Отключение стандартного поведения делается вот таким примитивным «плагином» (я его доработал, но об этом позже):
Код:
Game_Temp.prototype.setDestination = function(x, y) {
};
Scene_Map.prototype.isMenuCalled = function() {
return Input.isTriggered('menu');
};
И все, по нажатию ЛКМ и ПКМ в игре пока ничего не происходит – поиск пути не начинается, меню не открывается.
Что дальше? Координаты и клики!
Получение координат кликов.
Как же получить координаты кликов, да еще и раздельно? Гугл и зарубежные товарищи утверждают, что следующие команды Скрипта в Условии могут нам помочь (и это действительно так!):
Код:
TouchInput.isTriggered() – для ЛКМ.
TouchInput.isCancelled() – для ПКМ.
Все это вешаем на два Общих события (одно для ЛКМ, второе для ПКМ), работающие параллельно с каким-то переключателем – это позволит в дальнейшем, при необходимости, систему порталов отключать/включать.
На данном этапе нам нужно будет использовать три переменные и один переключатель, таким образом (номера выбираются произвольно):
- Переменная 21: координата X нажатия ЛКМ / ПКМ;
- Переменная 22: координата Y нажатия ЛКМ / ПКМ;
- Переменная 23: таг поверхности клетки, на которую нажали ЛКМ / ПКМ;
- Переключатель 21: факт того, что игра началась (Порталы можно ставить).
Как же получить значения для данных переменных? Воспользуемся тем фактом, что на клики ЛКП и ПКМ у нас повешены отдельные Общие события и в них пропишем такой Скрипт:
Код:
let xCoord = TouchInput.x;
let yCoord = TouchInput.y;
xCoord = $gameMap.canvasToMapX(xCoord);
yCoord = $gameMap.canvasToMapY(yCoord);
let terrainTag = $gameMap.terrainTag(xCoord , yCoord);
$gameVariables.setValue(21, xCoord);
$gameVariables.setValue(22, yCoord);
$gameVariables.setValue(23, terrainTag);
где:
TouchInput.x – координата X Окна мейкера для точки, где был клик;
TouchInput.y – координата Y Окна мейкера для точки, где был клик;
(хранятся в локальных переменных скрипта xCoord и yCoord соответственно).
$gameMap.canvasToMapXY(…локальная переменная координаты…) – получение координаты уже не точки Окна мейкера, а клетки карты на которой был клик при помощи встроенного в мейкер метода;
(хранятся в локальных переменных скрипта xCoord и yCoord соответственно).
$gameMap.terrainTag(xCoord , yCoord) – получение тага поверхности клетки исходя их координат клетки.
$gameVariables.setValue(…номер переменной мейкера… , …название локальной переменной скрипта…) – помещение полученных значений в переменные мейкера для удобства работы с ними.
В результате мы знаем, по какой клетке был клик ЛКМ / ПКМ и таг поверхности этой клетки!
Может возникнуть вопрос – а для чего нам таг клетки и что это вообще такое? Таг клетки («Код местности») – это дополнительная информация о клетке карты, а именно: числовой номер 0-7, задаваемый в разделы «Тайлсеты» в мейкере. Нужно нам это для того, что бы запретить создавать порталы в пустоте или стенах.
ПОРТАЛЫ
Перемещение порталов в место клика.
Усе, зная координаты клика можно перемещать туда Порталы. Для этого делаем ширину карты гораздо больше, чем будет доступно Игроку и создаем два эвента: Портал А и Портал Б – оба эвента находятся на одном уровне с Игроком и они Проходимы.
Перемещает Порталы в точку клика команда «Передвинуть событие» в наших Общих событиях – передвигать будем эвента Портал А и Портал Б в переменные координат, полученные ранее.
Но как-то это странновато. Можно ведь поставить Портал Б в клетку Портала А…Нужны проверки.
Проверки порталов.
Что же нужно проверять:
1. Для корректно размещения Порталов - Таг клетки.
2. Для Портала А – не поставлен ли он до этого;
3. Для Портала Б – не поставлен ли он до этого;
4. Для Портала А – не поставлен ли он в клетку Портала Б;
5. Для Портала Б – не поставлен ли он в клетку Портала А;
6. Для Портала А – поставлен ли уже Портал Б;
7. Для Портала Б – поставлен ли уже Портал А;
8. Для перемещения между Порталами - поставлены ли оба Портала.
Для этого используем еще переменные и переключатели мейкера, а именно:
- Переменная 25: координата X клетки Портала А;
- Переменная 26: координата Y клетки Портала А;
- Переменная 27: координата X клетки Портала Б;
- Переменная 28: координата Y клетки Портала Б;
- Переключатель 23: факт того, что Портал А поставлен;
- Переключатель 24: факт того, что Портал Б поставлен;
- Переключатель 25: факт того, что Порталы А и Б поставлены одновременно.
Проверки делаем стандартными условиями мейкера. Заодно можно поставить звуковое сопровождение для случаем активации Портала / невозможности Портал поставить.
Это довольно нудная, но необходимая часть.
После проверок.
Если все проверки проходят корректно, до в переменные 25 и 26 (или 27 и 28, в зависимости от того ЛКМ это или ПКМ) заносим координаты X и Y клика и активируем переключатель готовности соответствующего Портала; также, если противоположный Портал уже поставлен, активируем переключатель готовности всех Порталов.
Также задаем возможность снять Портал, при этом переменные 25 и 26 (или 27 и 28, в зависимости от того ЛКМ это или ПКМ) обнуляем, дезактивируем переключатель готовности соответствующего Портала и дезактивируем переключатель готовности всех Порталов!
…и можно перемещать Игрока и эвенты!
ПЕРЕМЕЩЕНИЕ
Контроль координат перемещаемого объекта.
Вот в этом моменте свобода реализации.
Можно сделать в Портале, при касании, перенесение к координатам к противоположному Порталу (если он поставлен)…но это будет работать только для Игрока.
Можно сделать проверку координат в еще одном Общем событии.
Я делаю вторым вариантом (Общее событие) – так как перемещать другие эвенты можно только так – и рассматриваю именно такую реализацию.
При этом, для удобства, я буду использовать плагин GALV_PuzzleFunctions – он позволяет упростить проверку совпадения координат Игрока и эвентов с координатами Порталов.
Общее событие перемещения.
Тут просто. Делаем Общее событие, которое работает параллельно с переключателем 25 (который значит, что оба Портала одновременно активны).
В событии для каждого перемещаемого объекта контролируем:
1. Совпадение координат с координатами X и Y Портала A.
2. Совпадение координат с координатами X и Y Портала Б.
Если координаты совпадают – переносим стандартными командами мейкера:
«Переместить игрока» для Игрока и «Передвинуть событие» для эвента.
При этом, для переноса Игрока, нужно использовать еще одну переменную (!), в которой будет храниться номер (ID) текущей карты:
- Переменная 29: номер (ID) текущей карты.
При помощи плагина GALV_PuzzleFunctions контроль координат сводится к тому, что в Условии мы выбираем «Скрипт» и пишем:
Код:
Galv.PUZ.isAt([$gameVariables.value(25), $gameVariables.value(26)], …номер эвента…)
где:
Galv.PUZ.isAt(…) – собственно, команда плагина;
[$gameVariables.value(…номер переменной…), …] – переменные координат X и Y соответствующего Портала;
номер эвента – номер (ID) перемещаемого эвента (для Игрока = 0).
Нюанс перемещения.
Портал, сам по себе, занимает 1 клетку. И при шаге в него Игрок / эвент «зависает» между двумя Порталами – точнее, после входа в первый Портал и перемещения ко второму мгновенно перемещается обратно.
Также это визуально «крадет» 1 шаг за счет размера Портала.
Такое поведение нам не нужно!
Для избежание этого после перемещения в Общем событии ставим для Игрока / эвента команду движения «Шаг вперед» - это заставляет перемещаемый объект сделать шаг по направлению движения.
И проблема решена!
ОГРАНИЧЕНИЕ
(В версии 2.0 убрано ограничена на размер карты!)
Нельзя смотреть из одного портала в другой. =)
ПОСЛЕСЛОВИЕ
Как видите, все просто.
Да, немножко муторно с проверкой условий Порталов.
И с тем, что для каждого перемещаемого между Порталами объекта, нужно вручную задавать контроль перемещения-перемещение-шаг вперед.
И с геймпада не поиграть.
Много нюансов, короче говоря. Но реализуемо ведь!
И теперь вы знаете, как это сделать.
Знание – сила.
ССЫЛКА НА ДЕМКУ, 2.0 :
БЛАГОРАДРНОСТИ
Нейтральной полосе и конкурсу RTP-2021 - ведь ничто не разжигает фантазию так, как ограничения!
Рольфу за мысль, что туториал таки нужен.
P.S
Обещал в конце мая, но закрутился с плагинами.
В принципе, сделать подобное можно и на VX Ace (а может и XP) - главное, что бы был доступ к координатам кликов мыши и отдельная обработка ЛКМ и ПКМ.
Также эту технику можно использовать не только для порталов, но и для других головоломок.
Возможно, для некоего подобия "шутера" тоже (но это не точно).
P.P.S
Ссылка на плагин от Galv MV Puzzle Functions:
https://galvs-scripts.com/2016/08/14...zle-functions/
Мой плагин DKR_PuzzleMouse частично упрощает разработку такой "системы" (в плане отключения стандартного поведения мыши и получения координат кликов), но в туториале и демке рассматривается реализация без него:
[MV + MZ]DKR_PuzzleMouse
Реализация на MZ в моем маленьком конкурсном проекте (проект не зашифрован, но там есть ограничение на размер карты!) :
https://rpgmaker.su/f102/[rtp2021]-kn6ep%D0%B1@r-4739/
update от 18.09.2021
Скорректировано преобразование координат окна в координаты карты – теперь оно осуществляется при помощи встроенных методов мейкера:
$gameMap.canvasToMapX(xCoord) и $gameMap.canvasToMapY(xCoord)
Это снимает ограничения на размер карты!
Обновлен туториал, скрины, демка.
Социальные закладки